#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "StdTcp.h"
#include "StdThread.h"
#include "../GlobalMessage.h"
#include "DoubleLinkList.h"
#include "DataCenter.h"
#include "StdThreadPool.h"
#include "FileSystem.h"

#define ip "192.168.27.129"
#define port 8085

DLlist ClientList; //在线用户列表
FileSys *fs;    //文件系统

char* GetOnlinelist()
{
    char* content = (char*)malloc(ContentSize);
    if(content == NULL)
    {
        printf("GetOnlinelist malloc error!\n");
        exit(-1);
    }
    memset(content,0,ContentSize);
    DLNode *travelPoint = ClientList.head->next;
    while(travelPoint != NULL)
    {
        CInfo *c = (CInfo*)travelPoint->data;
        strcat(content,c->ClientName);
        strcat(content,",");
        travelPoint = travelPoint->next;
    }
    content[strlen(content) - 1] = '\0';
    return content;
}


void SolveRequest(MSG *m,int clientSock)
{
    switch(m->flag)
    {
    //注册
    case SIGNUP:
        //当前用户名未被注册
        if(IsUserExist(m->FromName) == false)
        {
            if(AddNewUser(m->FromName,m->Content) == true)
            {
                InsertDLlistTial(&ClientList,CreateCInfo(m->FromName,clientSock));
                TravelDLlist(&ClientList,PrintCInfo);
                memset(m->Content,ContentSize,0);
                strcpy(m->Content,"注册成功");
                CreateNewDirInFs(fs,m->FromName);
            }
            else
            {
                memset(m->Content,ContentSize,0);
                strcpy(m->Content,"服务器错误");
            }
        }
        //用户名已被注册
        else
        {
            memset(m->Content,ContentSize,0);
            strcpy(m->Content,"用户名已被注册");
        }
        TcpServerSend(clientSock,m,sizeof(MSG));
        break;
    //登录
    case LOGIN:
        //账号是否存在
        if(IsUserExist(m->FromName) == true)
        {
            if(IsAccountEqual(m->FromName,m->Content) == true)
            {
                InsertDLlistTial(&ClientList,CreateCInfo(m->FromName,clientSock));
                TravelDLlist(&ClientList,PrintCInfo);
                memset(m->Content,ContentSize,0);
                strcpy(m->Content,"登录成功");
            }
            else
            {
                memset(m->Content,ContentSize,0);
                strcpy(m->Content,"账号密码错误");
            }
        }
        else
        {
            memset(m->Content,ContentSize,0);
            strcpy(m->Content,"账号不存在");
        }
        TcpServerSend(clientSock,m,sizeof(MSG));
        break;
    case CHAT:
    case SENDFILE:
        DLlist  findList = FindByElement(&ClientList,m->ToName,IsClientNameEqual);
        if(findList.len == 0)
        {
            printf("没有找到名称为|%s|的用户\n",m->ToName);
        }
        else
        {
            CInfo *c = (CInfo*)findList.head->next->data;
            printf("准备给|%s||套接字:%d|的用户发消息\n",c->ClientName,c->sock);
            TcpServerSend(c->sock,m,sizeof(MSG));
        }
        ClearDLlist(&findList,NULL);
        break;
    case BROADCAST:
        DLNode *travelPoint = ClientList.head->next;
        while(travelPoint != NULL)
        {
            CInfo *c = (CInfo*)travelPoint->data;
            if(strcmp(c->ClientName,m->FromName) != 0)
            {
                TcpServerSend(c->sock,m,sizeof(MSG));
            }
            travelPoint = travelPoint->next;
        }
        break;
    case ONLINELIST:
    {
        char *content = GetOnlinelist();
        printf("在线列表为:%s\n",content);
        strcpy(m->Content,content);
        TcpServerSend(clientSock,m,sizeof(MSG));
        free(content);
        break;
    }
    case UPLOAD:
    {
        int size = 0;
        memcpy(&size,m->Content,4);
        char fileName[NameSize] = {0};
        strcpy(fileName,m->Content + 4);
        WriteFileToFs(fs,m->FromName,fileName,m->Content + 24,size);
    }

    }
}


void *ClientHandle(void*arg)
{
    int clientSock = *((int*)arg);
    while (1)
    {
        MSG m;
        if(TcpServerRecv(clientSock,&m,sizeof(MSG)) == false)
        {
            printf("客户端|%d|已下线\n",clientSock);
            break;
        }
        // printf("收到来自客户端|%d|的消息:%s\n",clientSock,msg);
        SolveRequest(&m,clientSock);
    }

    //删除用户
    RemoveByElement(&ClientList,(void*)(intptr_t)clientSock,IsClientSockEqual,free);
    return NULL;
}

int main()
{
    if(DataCenterInit() == false)
    {
        printf("数据中心初始化失败!\n");
        return -1;
    }
    InitDLlist(&ClientList);
    TcpS *s = TcpServerInit(ip,port);
    ThreadP *p = ThreadPoolInit(10,2,10,3600);
    fs = FileSystemInit("./filesystem");

    int clientSock = -1;
    while((clientSock = TcpServerAccept(s)) >= 0)
    {
        printf("接入新的客户端，套接字是:%d\n",clientSock);
        ThreadPoolAddTask(p,ClientHandle,&clientSock);
    }
    return 0;
}